home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Add-Ons / After Dark / Joe Judge / Sphere ƒ / sphere.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-02  |  5.6 KB  |  229 lines  |  [TEXT/KAHL]

  1.  
  2.  
  3. #include <Picker.h>
  4.  
  5.  
  6. /*
  7.  * (NX, NY, NZ) is the light source vector -- length should be
  8.  * 100
  9.  */
  10. #define NX 48
  11. #define NY (-36)
  12. #define NZ 80
  13. #define NR 100
  14.  
  15. #define MIN(a,b) ( ( (a) < (b) ) ? (a) : (b) )
  16.  
  17. #define  LIMIT_RADIUS
  18.  
  19. #ifdef LIMIT_RADIUS
  20. #include <math.h>
  21. #define SQRT sqrt
  22. #else                                        // was testing other sq_root functions
  23. int ISqrt(register int n);
  24. #define SQRT ISqrt
  25. #endif
  26.  
  27. int errno;
  28.  
  29. typedef struct {
  30.     Rect        r;
  31.     int      width, height;
  32.     int      radius;
  33.     int      x0;        /* x center */
  34.     int      y0;        /* y center */
  35.     RGBColor    rgb;        // for > 8 bits
  36.     int      x;
  37.     int    maxy;            // was int, was double
  38. } spherestruct;
  39.  
  40. #define MAXSCREENS    4                        // maximum of 4 screens (lets not go crazy!)
  41. unsigned short RangedRdm( unsigned short min, unsigned short max );
  42. #define random() RangedRdm(0, 32767)
  43. RGBColor RandomRGBColor(void);
  44. RGBColor RandomIndexColor(short screenDepth);
  45.  
  46. static spherestruct spheres[MAXSCREENS];
  47.  
  48. void initsphere(int screen, Rect *theRect);
  49. void drawsphere(int screen, int screenDepth);
  50.  
  51. void
  52. initsphere(int screen, Rect *theRect)
  53. {
  54.     spherestruct *ss = &spheres[screen];
  55.  
  56.     ss->r = *theRect;
  57.     
  58.     ss->width = (theRect->right - theRect->left); //.width;
  59.     ss->height = (theRect->bottom - theRect->top); //.height;
  60.  
  61.     ss->x = ss->radius = 0;
  62. }
  63.  
  64. void
  65. drawsphere(int screen, int screenDepth)
  66. {
  67.     spherestruct *ss = &spheres[screen];
  68.     register short     y;
  69.     register short test;
  70.     short maxRadius;
  71.  
  72.     if (ss->x >= ss->radius) {
  73. #ifndef LIMIT_RADIUS
  74.         ss->radius = random() % (MIN(ss->width / 2, ss->height / 2)-1) + 1;
  75.         
  76.         ss->x0 = random() % ss->width;
  77.         ss->y0 = random() % ss->height;
  78.         ss->x = -ss->radius;
  79. #else    // limit the radius ... sqrt() sucks
  80.         maxRadius = MIN( 127,  (ss->width/2) );    // see comment below to see why 127
  81.         maxRadius = MIN( maxRadius, (ss->height/2) );
  82.  
  83.         // was silly to have a minimum of 1 as a sphere radius!
  84.         ss->radius = RangedRdm(2, maxRadius);        // sqrt() here fails when the high bit is set!
  85.         ss->x0 = RangedRdm(0, ss->width-1);
  86.         ss->y0 = RangedRdm(0, ss->height-1);
  87.         ss->x = -ss->radius;
  88. #endif
  89.  
  90.             
  91. // can't we do this later?
  92.         if (screenDepth > 8)
  93.             ss->rgb = RandomRGBColor();
  94.             //ss->color = random() % (1 << screenDepth );            // pick a random color
  95.         else if (screenDepth > 1)
  96.             ss->rgb = RandomIndexColor( screenDepth);
  97.     }
  98.  
  99.     ss->maxy = SQRT( (ss->radius * ss->radius) - (ss->x * ss->x) );
  100.         
  101.         
  102. //     if (errno == 33) SysBeep(0);
  103.  
  104. // if this vertical line is onscreen, draw it
  105. // do I need to worry about this test?
  106.     if (    ss->r.left + ss->x0 + ss->x >= ss->r.left &&
  107.             ss->r.left + ss->x0 + ss->x <= ss->r.right) {
  108.         ForeColor(blackColor);
  109.          MoveTo( ss->r.left + ss->x0 + ss->x, ss->r.top + ss->y0 - ss->maxy);
  110.          LineTo( ss->r.left + ss->x0 + ss->x, ss->r.top + ss->y0 + ss->maxy);  
  111.     }
  112.     
  113.  
  114.     if (screenDepth > 1)
  115.         RGBForeColor( &ss->rgb);
  116.     else
  117.         ForeColor( whiteColor);
  118.  
  119.  
  120.     for (y = -ss->maxy; y <= ss->maxy; y++) {
  121.         register short X, Y;
  122.         
  123.         X = ss->r.left + ss->x + ss->x0;
  124.         Y = ss->r.top + y + ss->y0;
  125.         
  126.         if (    (random() % (ss->radius * NR)) <= 
  127.                 (NX * ss->x + NY * y + NZ * 
  128.                     SQRT(ss->radius * ss->radius - ss->x * ss->x - y * y) ) )
  129.                     
  130. //            XDrawPoint(dsp, win, Scr[screen].gc, ss->x + ss->x0, y + ss->y0);
  131. #if 0                            
  132.                 MoveTo(X, Y);
  133.                 Line(0 , 0);
  134. #else
  135. #if 0
  136.                 if ( Y > ss->r.bottom)    // if we're past the bottom, this vert line is done
  137.                     break;
  138.                 if ( Y < ss->r.top)        // we not at the top ... continue the loop
  139.                     continue;        
  140. #endif
  141.                     
  142.                 if (    X >= ss->r.left && X <= ss->r.right) { // are we onscreen?
  143.                     if (screenDepth > 1)
  144.                         SetCPixel(X, Y, &ss->rgb); 
  145.                     else {
  146.                         MoveTo(X, Y);
  147.                         LineTo(X, Y);
  148.                         //SysBeep(0); // fix this!!
  149.                     }
  150.                 }
  151. #endif
  152.     }
  153.     ss->x++;
  154. }
  155.  
  156. RGBColor
  157. RandomIndexColor(short screenDepth) {
  158. short i;
  159. RGBColor rgb;
  160.     
  161.     i =  RangedRdm(0, (1 << screenDepth) - 2 ); // highest color == black
  162.     Index2Color(i, &rgb);
  163.     return rgb;
  164. }
  165.  
  166. RGBColor
  167. RandomRGBColor(void) {
  168. RGBColor rColor;
  169. short chance;
  170.  
  171.     chance = RangedRdm(0, 5);
  172.     
  173.     switch( chance) {
  174.     case 0:        // equal randomness
  175.         rColor.red = RangedRdm(0, 65535);
  176.         rColor.blue = RangedRdm(0, 65535);
  177.         rColor.green = RangedRdm(0, 65535);
  178.         break;
  179.     case 1:        // more red
  180.         rColor.red = RangedRdm(32767, 65535);
  181.         rColor.blue = RangedRdm(0, 65535);
  182.         rColor.green = RangedRdm(0, 65535);
  183.     case 2:        // more blue
  184.         rColor.red = RangedRdm(0, 65535);
  185.         rColor.blue = RangedRdm(32767, 65535);
  186.         rColor.green = RangedRdm(0, 65535);
  187.     case 3:        // more green
  188.         rColor.red = RangedRdm(0, 65535);
  189.         rColor.blue = RangedRdm(0, 65535);
  190.         rColor.green = RangedRdm(32767, 65535);
  191.  
  192.     default:        // brighter hues of any color
  193.         {
  194.             HSVColor hColor;
  195.  
  196.             hColor.hue = (SmallFract)(RangedRdm(0, 65535) );
  197.             hColor.saturation = (SmallFract)RangedRdm( 49150, 65535);
  198.             hColor.value = (SmallFract) RangedRdm( 49150, 65535);
  199.             HSV2RGB( &hColor, &rColor);
  200.         }
  201.     }
  202.     return rColor;
  203. }
  204.  
  205.  
  206.  
  207. // this is from the Think C reference code example ...
  208. unsigned short RangedRdm( unsigned short min, unsigned short max )
  209. /* assume that min is less than max */
  210. {
  211.     // uh ... not this isn't quite right - it's between 0 and 65535, not 65536
  212.     //  -----------------------------------------vvvvv
  213.     unsigned    qdRdm;    /* treat return value as 0-65536 */
  214.     long    range, t;
  215.     
  216.     // just to be safe, I'll put this here
  217.     if (min > max) DebugStr("\pMin greater then Max in RangedRdm");
  218.     
  219.     qdRdm = Random();
  220.     range = max - min;
  221.     // max - min gives us the the difference between max and min ... that is 
  222.     // not inclusive. It gives us { min <= range < max }
  223.     // so we never see that max number!!
  224.     range++;
  225.     t = ((long)qdRdm * range) / 65536;     /* now 0 <= t <= range */
  226.     return( t+min );
  227. }
  228.  
  229.